package com.ocom.webapi.po;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

public class RSADemo4 {
    private static final Logger log = LoggerFactory.getLogger(RSADemo4.class);
    public static final String RSA_ALGORITHM = "RSA";

    public RSADemo4() {
    }

    public static Map<String, String> createKeys(int KeySize) {
        KeyPairGenerator kpg;
        try {
            kpg = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException var9) {
            throw new IllegalArgumentException("No such algorithm-->[RSA]");
        }

        try {
            kpg.initialize(KeySize);
            KeyPair KeyPair = kpg.generateKeyPair();
            Key publicKey = KeyPair.getPublic();
            String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded());
            Key privateKey = KeyPair.getPrivate();
            String privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded());
            Map<String, String> KeyPairMap = new HashMap();
            KeyPairMap.put("publicKey", publicKeyStr);
            KeyPairMap.put("privateKey", privateKeyStr);
            return KeyPairMap;
        } catch (Exception var8) {
            var8.printStackTrace();
        }
        return null;
    }

    public static String publicEncrypt(String data, String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException {
        RSAPublicKey publicKeyObj = getPublicKey(publicKey);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(1, publicKeyObj);
        return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, 1, data.getBytes(StandardCharsets.UTF_8), publicKeyObj.getModulus().bitLength()));
    }

    public static String privateDecrypt(String data, String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException {
        RSAPrivateKey privateKeyObj = getPrivateKey(privateKey);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(2, privateKeyObj);
        return new String(rsaSplitCodec(cipher, 2, Base64.decodeBase64(data), privateKeyObj.getModulus().bitLength()), StandardCharsets.UTF_8);
    }

    private static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
        return (RSAPublicKey)keyFactory.generatePublic(x509KeySpec);
    }

    private static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
        return (RSAPrivateKey)keyFactory.generatePrivate(pkcs8KeySpec);
    }

    private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int KeySize) {
        int maxBlock;
        if (opmode == 2) {
            maxBlock = KeySize / 8;
        } else  {
            maxBlock = KeySize / 8 - 11;
        }

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offset = 0;
        int i = 0;

        try {
            while (datas.length > offset) {
                byte[] buff;
                if (datas.length - offset > maxBlock) {
                    buff = cipher.doFinal(datas, offset, maxBlock);
                } else  {
                    buff = cipher.doFinal(datas, offset, datas.length - offset);
                }

                out.write(buff, 0, buff.length);
                ++i;
                offset = i * maxBlock;
            }
        } catch (Exception var10) {
            log.error("[commons RSAUtil rsaSplitCodec]: Cipher={}, opmode={}, error={}", new Object[]{cipher, opmode, var10.getMessage(), var10});
            var10.printStackTrace();
        }

        byte[] resultdatas = out.toByteArray();
        IOUtils.closeQuietly(out);
        return resultdatas;
    }

    public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, UnsupportedEncodingException {

        //接收到链接后不需要进行decode,直接解密
//        String decode = "K-eeICn8XVZnaFvHah7Asv0AhRX8MVRLj3xf3bGTOjJ_nf2ZkDLiE7lhIkHQL-KhoRre-rtX7d5WTvFlHXWOv3L150vLHVsLJs0SJ6ghmbDoLnbn7rClT0Oh9OEq9BqwYhr93HJ74Dq5UM19oL3fxKuAO0kmdjmMPmWkFWDySmk";
        String decode = "OHQfAt3ubXhnsL62eQKsjUsHnQxL0tEMFpDScQ2_agoO3NsY9brMnLOGu1_geoF4CV9mRdGDNtbSP7tV8aibwXjPOW1uHirrzxR5RFY-oSxOUXqUGy5XwsWFhKxbE2z2gDzMlEQP-E-kootE5nO8sKeTaCuH_laFZpIWVI2HUJ4";
        if(decode.contains("%2C")){
            String[]  strs=  decode.split("%2C");
            decode= strs[0];
        }
        System.out.println(decode);
        System.out.println(privateDecrypt(decode,zhxy_pri_key));
    }
    //a9998a01179d11eeb66bc7a83f01e717
    //a9998a01179d11eeb66bc7a83f01e717
    //

    static  String zhxy_pri_key = "MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAhQKrwgMA9qQP2bn6VB-bVUoQEGHmWAucuOMvbN5IXfg-XQvaGKhAVv_hIbZNYBOTZsS8aYtL8d45vM4HGBQSFQIDAQABAkANJLJsPXe-539ZeHMwFN94khT8SXBFiwA1lN1-2Ig2IMksgAd6ICLOKtuiXntAGNaNRYAWOJ23f8WIGdmTKQWRAiEAvj2dKiK8Oi8DjuQr41X9CmIrcyoBnDI6ypzS9xnLn2MCIQCy_MGLWWVs2Dnq8CKfOYVur69emxAXyduG2SqXTlkuJwIgJllPRD4qSWROyFAwlKwxzRULAzUVjAIIHe3NDSizBlcCICy_tp_hRNNWp_xN90n5tpt6vwyXFgnshL8NEnHru64nAiBFhMs4wUBcAM8scM9ZBSHZ0ldu_K3owPloa6g6aDq6vQ";
}